<?php

namespace App\Services;

use App\Exceptions\CouponCodeUnavailableException;
use App\Exceptions\InvalidRequestException;
use App\Models\CouponCode;
use App\Models\Order;
use App\Models\ProductSku;
use App\Models\User;
use App\Models\UserAddress;
use App\Jobs\CloseOrder;
use Carbon\Carbon;
use Auth;

class OrderService
{
    public function get()
    {
        return Auth::user()->orders()->with(['items.product', 'items.productSku'])->latest()->paginate();
    }

    /**
     * 提交订单
     *
     * @param UserAddress $address
     * @param $remark
     * @param array $items
     * @return mixed
     */
    public function store(User $user, UserAddress $address, $remark, array $items, CouponCode $coupon = null)
    {
        if (!is_null($coupon)){
            $coupon->checkAvailable($user);
        }

        $order = \DB::transaction(function () use ($address, $remark, $items, $coupon){
            // 更新收货地址最后使用时间
            $user = Auth::user();
            $address->update([
                'last_used_at' => Carbon::now(),
            ]);

            // 创建一个订单
            $order = new Order([
                'address' => [
                    'address' => $address->full_address,
                    'zip' => $address->zip,
                    'contact_name' => $address->contact_name,
                    'contact_phone' => $address->contact_phpne,
                ],
                'remark' => $remark,
                'total_amount' => 0
            ]);

            // 订单关联当前用户
            $order->user()->associate($user);
            $order->save();

            $totalAmount = 0;
            foreach ($items as $item){
                // 创建一个OrderItem并直接与当前订单关联
                $sku = ProductSku::find($item['sku_id']);
                $item = $order->items()->make([
                    'amount' => $item['amount'],
                    'price' => $sku->price,
                ]);
                $item->product()->associate($sku->product_id);
                $item->productSku()->associate($sku);
                $item->save();

                $totalAmount += ($sku->price * $item['amount']);

                // 减库存
                if ($sku->decreaseStock($item['amount']) <= 0){
                    throw new InvalidRequestException('该商品库存不足');
                }
            }

            if ($coupon){
                $coupon->checkAvailable($user, $totalAmount); // 检查订单金额
                $totalAmount = $coupon->getAdjustedPrice($totalAmount); // 获取优惠后订单金额
                $order->couponCode()->associate($coupon); // 订单关联优惠券
                if ($coupon->changeUsed() <= 0){ // 更新优惠券使用量
                    throw new CouponCodeUnavailableException('该优惠券已兑完');
                }
            }

            // 更新订单总金额
            $order->update(['total_amount' => $totalAmount]);

            // 清理购物车
            $skuIds = collect($items)->pluck('sku_id');
            $user->cartItems()->whereIn('product_sku_id', $skuIds)->delete();

            return $order;
        });

        dispatch(new CloseOrder($order, config('app.order_ttl')));
        return $order;
    }


}